home *** CD-ROM | disk | FTP | other *** search
- ;* START.ASM
- ;************************************************************************
- ;* *
- ;* PC Scheme/Geneva 4.00 Borland TASM code *
- ;* *
- ;* (c) 1985-1988 by Texas Instruments, Inc. See COPYRIGHT.TXT *
- ;* (c) 1992 by L. Bartholdi & M. Vuilleumier, University of Geneva *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Startup & Exit code for Borland C *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Created by: John Jensen Date: 1985 *
- ;* Revision history: *
- ;* - 18 Jun 92: Renaissance (Borland Compilers, ...) *
- ;* *
- ;* ``In nomine omnipotentii dei'' *
- ;************************************************************************
- IDEAL
- %PAGESIZE 60, 132
- MODEL medium
- LOCALS @@
-
- INCLUDE "scheme.ash"
-
- DATASEG
-
- EXTRN C _psp:word, C _argc:word, C _argv:word
-
- prev_mode DB ?, 0
-
- ; the characters sought by PCS's scanner
- scan_table DB 0dh, 9, ' ()"', ?
- SCANSIZE = $-scan_table
-
- ; the FSA transition table used to parse PCS's command line
- ; (This once included handling for vertical-bar delimited symbols, but
- ; DOS's use of | rendered it useless, so it was removed.)
-
- STRUC TRANSITION
- tstate DB ?
- taction DB ?
- ENDS TRANSITION
-
- MACRO TRANS st, act
- DB st
- DB act-pcsparse
- ENDM
-
- LABEL state TRANSITION
- STARTSTATE = 0
- TRANS ATOMSTATE, ar_start ; any char
- TRANS STRINGSTATE, ar_start ; "
- TRANS ERRORSTATE, ar_err ; )
- TRANS LISTSTATE, ar_startl ; (
- TRANS STARTSTATE, ar_skip ; blank
- TRANS STARTSTATE, ar_skip ; tab
- TRANS ENDSTATE, ar_end ; CR (end of command line)
- BYTESSTATE = $-state
- LISTSTATE = 1
- TRANS LISTSTATE, ar_loop
- TRANS LISTSTATE, ar_loop
- TRANS LISTSTATE, ar_rpar
- TRANS LISTSTATE, ar_lpar
- TRANS LISTSTATE, ar_loop
- TRANS LISTSTATE, ar_loop
- TRANS ERRORSTATE, ar_err
- ATOMSTATE = 2
- TRANS ATOMSTATE, ar_loop
- TRANS ATOMSTATE, ar_loop
- TRANS ATOMSTATE, ar_loop
- TRANS ATOMSTATE, ar_loop
- TRANS STARTSTATE, ar_skip
- TRANS STARTSTATE, ar_skip
- TRANS ENDSTATE, ar_end
- STRINGSTATE = 3
- TRANS STRINGSTATE, ar_loop
- TRANS STARTSTATE, ar_loop
- TRANS STRINGSTATE, ar_loop
- TRANS STRINGSTATE, ar_loop
- TRANS STRINGSTATE, ar_loop
- TRANS STRINGSTATE, ar_loop
- TRANS ERRORSTATE, ar_err
- ENDSTATE = 4
- ERRORSTATE = 5
-
- ; The exit and error states are not explicitly represented
- ; in the table, action routines deal with them.
-
- parserr DB "Error in parsing command line", 0dh, 0ah, "$"
-
- CODESEG
-
- ; -------------------------------------------------
- ; StartText - Ensure PCS start in text mode
- ; -------------------------------------------------
-
- PROC C starttext USES si di
- mov ah, 0fh ; get current video mode
- int IBM_CRT
- mov [prev_mode], al ; save it until PCS exit
- call is_graph_mode
- or ax, ax
- jz @@textmode
- mov ax, 7 ; Try monochrome mode
- int IBM_CRT
- mov ax, 3 ; Try CGA mode (the good'll work!)
- int IBM_CRT
- @@textmode:
- call zcuroff C ; Turn cursor off (and remember size)
- ret
- ENDP starttext
-
- ; -------------------------------------------------
- ; ExitText - Put back previous mode when PCS exit
- ; -------------------------------------------------
-
- PROC C exittext USES si di
- mov ah, 0fh ; get current video mode
- int IBM_CRT
- cmp [prev_mode], al ; same as on entry ?
- jz @@ret
- mov ax, [WORD prev_mode] ; set video mode
- int IBM_CRT
- @@ret:
- call zcuron C ; Turn cursor back on
- ret
- ENDP exittext
-
- ; -------------------------------------------------
- ; The PCS command line parser
- ; -------------------------------------------------
- ; The PCS command line looks as follows:
- ;
- ; PCS <arglist>
- ; where:
- ; arglist ::= [<item> <arglist>]
- ; item ::= (<arglist>) | <atom> | "<string>"
- ; atom ::= <blackchar>[<atom>]
- ; string ::= [<anychar><string>]
- ; anychar ::= <blackchar> | white space
- ; blackchar ::= a character | \<allchars>
- ; allchars ::= absolutely anything, except null char
- ;
- ; eg. PCS (abc "def") is (a (silly ("\"example for you\"")))
- ;
- ; which parses into PCS-INITIAL-ARGUMENTS as:
- ;
- ; ("(abc \"def\")" "is" "(a (silly (\"\"example for you\"\")))"),
- ; when (let ((p (open-input-string (caddr pcs-initial-arguments))))
- ; (string->atom (caddr (read p)))))
- ; would return "example for you".
- ;
- ; Each command line argument is either an atom, list, or string.
- ; Each is treated as one argument for the argv vector, and each is
- ; converted to a string which becomes an element of PCS-INITIAL-ARGUMENTS.
- ;
- ; The command line parser is not a Scheme reader. It looks for blank-separated
- ; tokens, where a token can start with a ( and end with the matching ),
- ; start and end with a ", or just be a sequence of nonblanks. Backslashed
- ; delimiters are skipped over as you'd expect. We don't bother with | since
- ; that is a special character to DOS.
- ;
- ; The first command line argument has special meaning but that is
- ; handled in "smain.c".
- ;
- PROC C pcsparse USES si di
- mov es, [_psp]
- mov si, 81h
- mov bl, [es:si-1]
- mov bh, 0
- mov [BYTE es:si+bx], 0dh; ensure command is CR-terminated
- inc bx
- push bx
- @@skipspace:
- cmp [BYTE es:si], ' '
- je @@found
- cmp [BYTE es:si], 9
- jne @@done
- @@found:
- dec bx
- inc si
- jmp @@skipspace
- @@done:
- call malloc C, bx
-
- push ds es
- pop ds es
-
- or ax, ax
- je ar_err
- mov di, ax
- pop cx
- cld
- rep movsw ; move the arguments to our new block
- push es
- pop ds
-
- mov di, [_argv]
- add di, 2 ; leave argv[0] unchanged; es:di is argv
- mov si, ax ; ds:si is command line
- mov ah, 0 ; ah is current state
- ; al is current character
- mov dx, 1 ; dh is parenthesis counter
- ; dl is argument count
- cld
- ar_loop:
- @@loop:
- lodsb
- cmp al, '\' ; is it singly escaped?
- jne @@singlesc
- cmp [BYTE si], 0dh ; end of cmdline ?
- je ar_err
- inc si
- jmp @@loop
- @@singlesc:
- mov cx, SCANSIZE ; look it up in char table
- push di
- lea di, [scan_table]
- repne scasb ; put into cx the "char class" for
- ; indexing into state table
- pop di
- mov al, BYTESSTATE ; do 2-D subscript into state table
- mul ah ; ... row
- shl cx, 1 ; ... col
- add ax, cx
- mov bx, ax ; (bh=0 since subscript small enough)
- mov ah, [state+bx.tstate]
- mov bl, [state+bx.taction]
- add bx, OFFSET pcsparse
- jmp bx
-
- ar_startl:
- inc dh
- ar_start:
- push ax
- lea ax, [si-1]
- stosw
- pop ax
- inc dl
- jmp @@loop
- ar_lpar:
- inc dh ; incr paren count
- jmp @@loop
- ar_rpar:
- dec dh ; decr paren count
- js ar_err
- jnz @@loop
- mov ah, STARTSTATE ; override state in table
- jmp @@loop
- ar_skip:
- mov [BYTE si-1], 0 ; output a null char
- jmp @@loop
- ar_err:
- lea dx, [parserr] ; abort on error in cmdline parsing
- mov ah, 9
- int 21h
- mov ax, 4cffh
- int 21h
- ar_end:
- xor ax, ax
- mov [BYTE si-1], al ; put a null here too
- stosw ; argv[argc] is NULL
- mov [_argc], dx
- ret
- ENDP pcsparse
-
- ;
- ; Scheme wrapup - the C fn "exit" calls "_exit" which calls this hook routine
- ;
-
- PROC C pcsexit USES si di
- cmp [mouse_use], 0
- je @@nomouse
- mov ax, 0 ; reset mouse handler
- int 33h
- mov [mouse_use], 0 ; disable mouse
- @@nomouse:
- push es ; return Scheme heap to DOS
- mov ah, 49h
- mov es, [first_dos]
- int MSDOS
- pop es
- mov dx, [emshandle]
- cmp dx, 0ffffh
- je @@noems
- mov ah, 45h ; release EMS handle
- int EMMINT
- @@noems:
- call rsttimer C ; Reset the timer interrupt, if necessary
- call unfixint C ; Restore the keyboard "patch" (MWH2)
- ret
- ENDP pcsexit
-
- ; Installation of the startup/exit code (#pragma startup/exit)
-
- SEGMENT _INIT_ word public 'INITDATA'
- DB 1 ; 1 = far, 0 = near
- DB 100 ; default priority
- DD starttext
- DB 1 ; 1 = far, 0 = near
- DB 100 ; default priority
- DD pcsparse
- ENDS _INIT_
-
- SEGMENT _EXIT_ word public 'EXITDATA'
- DB 1 ; 1 = far, 0 = near
- DB 100 ; default priority
- DD exittext
- DB 1 ; 1 = far, 0 = near
- DB 100 ; default priority
- DD pcsexit
- ENDS _EXIT_
-
- END